#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <sys/epoll.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/stat.h>
#include <ctype.h>
#define MAXSIZE 2000

#include "http.h"
#include "redirect.h"

static void parse_addr_and_port(const char *hostname, const char *addr, int *port) {
    printf("\033[42m%s\033[0m\n", hostname);
    sscanf(hostname, "%[^:]:%d", addr, port);
}

int init_redirect_client(const char *hostname) {
    char host_back[20];
    int port_back;
    parse_addr_and_port(hostname, host_back, &port_back);

    int sck = socket(AF_INET, SOCK_STREAM, 0);
	
	struct sockaddr_in s_addr, c_addr;
	s_addr.sin_family = AF_INET;
	s_addr.sin_port = htons(port_back);
	s_addr.sin_addr.s_addr = inet_addr(host_back);
	
	int ret = connect(sck, (struct sockaddr *)&s_addr, sizeof(s_addr));
	if (ret < 0) {
        printf("%s ***** %d\n", host_back, port_back);
		perror("connect error");
		return -1;
	}
    return sck;
}

// Open fd, then redirect them
void run_redirect(int port_front, char *hostname, const char *home, const char *root) {
    int epfd = epoll_create(MAXSIZE);
    // 添加要监听的节点
    // 先添加监听lfd
    int lfd = init_listen_fd(port_front, epfd);

    // 委托内核检测添加到树上的节点
    struct epoll_event all[MAXSIZE];

    // Create request fd
    

    while(1)
    {
        int ret = epoll_wait(epfd, all, MAXSIZE, -1);
        if(ret == -1)
        {
            perror("epoll_wait error");
            exit(1);
        }

        // 遍历发生变化的节点
        for(int i=0; i<ret; ++i)
        {
            // 只处理读事件, 其他事件默认不处理
            struct epoll_event *pev = &all[i];
            if(!(pev->events & EPOLLIN))
            {
                // 不是读事件
                continue;
            }
            if(pev->data.fd == lfd)
            {
               // 接受连接请求
                do_accept(lfd, epfd);
            }
            else
            {
               // 读数据
                int reqfd = init_redirect_client(hostname);
                do_redirect(pev->data.fd, reqfd, epfd);
            }
        }
    }
}

void do_redirect(int cfd, int reqfd, int epfd) {
    char buf[1024];
    int ret = 42;
    while(ret > 0) {
		ret = recv (cfd, buf, sizeof(buf), 0);
        ret = send (reqfd, buf, ret, 0);
    }
    ret = 42;
    while(ret > 0) {
		ret = recv (reqfd, buf, sizeof(buf), 0);
        ret = send (cfd, buf, ret, 0);
    }
    disconnect(cfd, epfd);
    close(reqfd);
}
